%------------------------------------------------------------
% Author: vjache
% Created: 30.10.2009
% Description: 	This module specifies an interface (or behavior) 
%				for Key->Value mappings store tools.
%				API contains a basic functions and also bulk
%				ones. E.g. m_pipe(...) returns a pipe through
%				which a user code may push a bulk series of 
%				modifications.
%------------------------------------------------------------
-module(map).

%------------------------------------------------------------
% Include files
%------------------------------------------------------------
-include("../include/map.hrl").
-include("../include/iter.hrl").
%------------------------------------------------------------
% Exported Functions
%------------------------------------------------------------
-export([
		 close/1,
		 clear/1,
		 contains/2,
		 entries_by_key/2,
		 entries_by_keys/2,
		 get/2,
		 keys/1,
		 m_iter/2,
		 m_pipe/1,
		 open/1,
		 put/3,
		 put_entries/2,
		 remove_entries/2,
		 remove_entry/3,
		 remove_key/2,
		 remove_keys/2,
		 size/1,
		 values_by_key/2,
		 values_by_keys/2
		]).
%------------------------------------------------------------
% API Functions
%------------------------------------------------------------

%% --------------------------------------------------------------------
%% Function: open(MapSpec)->Handle
%% Description: Opens a new map and returns handle ready to be used.
%% --------------------------------------------------------------------
open(#map{impl=Impl,param=Param})->
	Handle=Impl:open(Param),
	{Impl,Handle}.
%% --------------------------------------------------------------------
%% Function: close(Handle)->ok
%% Description: Closes map. During this call map releases all underlying 
%%				resources and any further calls with Handle will throw an 
%%				exception.
%% --------------------------------------------------------------------
close({Impl,Handle})->
	Impl:close(Handle),
	ok.
%% --------------------------------------------------------------------
%% Function: put(Handle,Key,Value)->ok
%% Description: Puts to map entry.
%% --------------------------------------------------------------------
put({Impl,Handle},Key,Value)->
	Impl:put(Handle,Key,Value),
	ok.
%% --------------------------------------------------------------------
%% Function: get(Handle,Key)->{ok,Value}|undefined
%% Description: Returns a value corresponding to Key. If there ara many 
%%				values for Key then returned some any one.
%% --------------------------------------------------------------------
get({Impl,Handle},Key)->
	Impl:get(Handle,Key).
%% --------------------------------------------------------------------
%% Function: remove_key(Handle,Key)->ok
%% Description: Removes all entries corresponding to Key.
%% --------------------------------------------------------------------
remove_key({Impl,Handle},Key)->
	Impl:remove_key(Handle,Key),
	ok.
%% --------------------------------------------------------------------
%% Function: remove_entry(Handle,Key,Value)->ok
%% Description: Remove specified entry if any.
%% --------------------------------------------------------------------
remove_entry({Impl,Handle},Key,Value)->
	Impl:remove_entry(Handle,Key,Value),
	ok.
%% --------------------------------------------------------------------
%% Function: entries_by_key(Handle,Key)->[{Key,Value}]
%% Description: Returns a list of entries corresponding to Key.
%% --------------------------------------------------------------------
entries_by_key({Impl,Handle},Key)->
	Impl:entries_by_key(Handle,Key).
%% --------------------------------------------------------------------
%% Function: values_by_key(Handle,Key)->[Value].
%% Description: Returns a list of values corresponding to Key.
%% --------------------------------------------------------------------
values_by_key({Impl,Handle},Key)->
	Impl:values_by_key(Handle,Key).
%% --------------------------------------------------------------------
%% Function: size(Handle)->int().
%% Description: Returns a size of map, i.e. total number of entries.
%% --------------------------------------------------------------------
size({Impl,Handle})->
	Impl:size(Handle).
%% --------------------------------------------------------------------
%% Function: contains(Handle,Key)->true|false.
%% Description: Checks whether the Key contained by this map.
%% --------------------------------------------------------------------
contains({Impl,Handle},Key)->
	Impl:contains(Handle,Key).
%% --------------------------------------------------------------------
%% Function: clear(Handle)->ok.
%% Description: Makes this map empty.
%% --------------------------------------------------------------------
clear({Impl,Handle})->
	Impl:clear(Handle),
	ok.
%------------------------------------------------------------
% Bulk API
%------------------------------------------------------------
put_entries(H,EntryList) when is_list(EntryList) ->
	put_entries(H,iter:from_list(EntryList)),
	ok;
put_entries({Impl,Handle},EntryIter) when ?IS_ITER(EntryIter) ->
	Impl:put_entries(Handle,EntryIter),
	ok.

values_by_keys(H,KeyList) when is_list(KeyList) ->
	values_by_keys(H,iter:from_list(KeyList));
values_by_keys({Impl,Handle},KeyIter) when ?IS_ITER(KeyIter) ->
	Impl:values_by_keys(Handle,KeyIter).

entries_by_keys(H,KeyList) when is_list(KeyList) ->
	entries_by_keys(H,iter:from_list(KeyList));
entries_by_keys({Impl,Handle},KeyIter) when ?IS_ITER(KeyIter) ->
	Impl:entries_by_keys(Handle,KeyIter).

remove_entries(H,EntryList) when is_list(EntryList) ->
	remove_entries(H,iter:from_list(EntryList)),
	ok;
remove_entries({Impl,Handle},EntryIter) when ?IS_ITER(EntryIter) ->
	Impl:remove_entries(Handle,EntryIter),
	ok.

remove_keys(H,KeyList) when is_list(KeyList) ->
	remove_keys(H,iter:from_list(KeyList)),
	ok;
remove_keys({Impl,Handle},KeyIter) when ?IS_ITER(KeyIter) ->
	Impl:remove_keys(Handle,KeyIter),
	ok.

keys({Impl,Handle})->
	Impl:keys(Handle).

m_pipe({Impl,Handle})->
	Impl:m_pipe(Handle),
	ok.
m_iter({Impl,Handle},ModifIter) when ?IS_ITER(ModifIter) ->
	Impl:m_iter(Handle,ModifIter),
	ok.
%------------------------------------------------------------
% Local Functions
%------------------------------------------------------------

